package com.univrz.flexmachine.core
{
	import com.univrz.flexmachine.scmxml.Transition;
	
	
	
/**
 *  
 * 
 *  @eventType com.univrz.flexmachine.events.StateMachineEvent.IS_ACTIVE_CHANGED
 */
[Event(name="isActiveChanged", type="com.univrz.flexmachine.events.StateMachineEvent")]		
	
	
	/**
	 * 
	 * An activable node can enter( ) and exit( ).
	 * Its active property changes accordingly.
	 * 
	 * They are the base class of States, Initial, Final and Join nodes.
	 * 
	 * @author abucchi
	 * 
	 */	
	public class ActivableNode extends Node
	{
	
	
		private var _isActive:Boolean;
		[Bindable("isActiveChanged")]
		public function get isActive():Boolean
		{
			return _isActive;
		}
	
	
	
	
	
	

		protected var inboundTransitions:Array;
	
		public function registerInboundTransition( transition:Transition ):void
		{
			inboundTransitions.push( transition );			
		}	
	

		public function acceptInboundTransition( transition:Transition ):void
		{
		
		
		
		
		}	
	
	
	
	
	
	
	
	
	
	
	
	
	
		
		////////////////////////////////////////////////////////////////
		///////////////////////// enter / exit /////////////////////////
		////////////////////////////////////////////////////////////////
		
		
		public function getClosestActiveNode( inclusive:Boolean = false ):ActivableNode
		{

			if ( inclusive && isActive )
				return this;

			var p:ActivableNode = parent as ActivableNode;

			if ( p == null )
				return null; // this should only happen if the state machine is not active
			
			return p.getClosestActiveNode( true );			
		
		}
		
		
		
		/**
		 * 
		 * Called when a transition enters this node explicitly
		 * 
		 */		
		public function enterHere( ):void
		{
			
			
			
		}
		
		

		/**
		 * 
		 * @param finalTarget
		 * 
		 */		
		public function enter( finalTarget:ActivableNode ):void
		{
			
			// different classes override this...
			
			
		
		}
		
		
		/**
		 * 
		 * Exiting is the easiest.
		 * All of our children exit, then we do ( recursively )
		 * 
		 * @param inclusive
		 * 
		 */		
		public function exit( inclusive:Boolean = false ):void
		{
			
			if ( ! isActive )
			{
				return;			
			}
			
			// tell all our childNodes to exit
			for each ( var child:ActivableNode in children )
			{
				child.exit( true );			
			}
			
			// all our childs have exited at this point
			if ( inclusive )
			{
				doExitBusiness();
			}
		}
		
		
		
		protected function doExitBusiness( ):void
		{
			// most node types don't do anything special when exiting
			// others override this function
			// and perform some actions		
		}		
		
	
	
	
	}
	
}